package cn.edu.xmu.oomall.customer.controller;

import cn.edu.xmu.oomall.core.model.VoObject;
import cn.edu.xmu.oomall.core.util.Common;
import cn.edu.xmu.oomall.core.util.JacksonUtil;
import cn.edu.xmu.oomall.core.util.ReturnNo;
import cn.edu.xmu.oomall.customer.model.vo.ModifyCustomerVo;
import cn.edu.xmu.oomall.customer.model.vo.ModifyPwdVo;
import cn.edu.xmu.oomall.customer.model.vo.ResetPwdVo;
import cn.edu.xmu.oomall.customer.model.vo.SimpleLoginCustomerVo;
import cn.edu.xmu.oomall.customer.service.CustomerAccountService;
import cn.edu.xmu.privilegegateway.annotation.aop.Audit;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginName;
import cn.edu.xmu.privilegegateway.annotation.aop.LoginUser;
import cn.edu.xmu.oomall.core.util.ReturnObject;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Jiazhe Yuan
 * @date 2021-12-14 12:12:59
 */
@RestController
@RequestMapping(value = "/customer", produces = "application/json;charset=UTF-8")
public class CustomerAccountController {

    @Autowired
    private CustomerAccountService customerAccountService;

    @Autowired
    private HttpServletResponse httpServletResponse;

    @PostMapping("/login")
    public Object login(@Validated @RequestBody SimpleLoginCustomerVo simpleLoginCustomerVo, BindingResult bindingResult) {
        var res = Common.processFieldErrors(bindingResult, httpServletResponse);
        if (res != null) {
            httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return res;
        }

        ReturnObject returnObject = customerAccountService.login(simpleLoginCustomerVo.getUserName(), simpleLoginCustomerVo.getPassword());
        switch (returnObject.getCode()) {
            case CUSTOMER_INVALID_ACCOUNT:
                httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                break;
            case CUSTOMER_FORBIDDEN:
                httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
                break;
            default:
                httpServletResponse.setStatus(HttpServletResponse.SC_CREATED);
                break;
        }
        return Common.decorateReturnObject(returnObject);
    }

    @Audit
    @GetMapping("/logout")
    public Object logout(@LoginUser Long loginUser) {
        ReturnObject returnObject = customerAccountService.logout(loginUser);
        return Common.decorateReturnObject(returnObject);
    }

    @Audit
    @GetMapping("/self")
    public Object getOwnAccount(@LoginUser Long loginUser) {
        ReturnObject returnObject = customerAccountService.getOwnAccount(loginUser);
        return Common.decorateReturnObject(returnObject);
    }

    @Audit
    @PutMapping("/self")
    public Object modifyOwnAccount(@LoginUser Long loginUser,
                                   @LoginName String loginName,
                                   @Validated @RequestBody ModifyCustomerVo modifyCustomerVo,
                                   BindingResult bindingResult) {
        var res = Common.processFieldErrors(bindingResult, httpServletResponse);
        if (res != null) {
            return res;
        }
        ReturnObject returnObject = customerAccountService.modifyOwnAccount(loginUser, loginUser, loginName, modifyCustomerVo);
        return Common.decorateReturnObject(returnObject);
    }

    @PutMapping("/customers/password")
    public Object modifyPassword(@Validated @RequestBody ModifyPwdVo modifyPwdVo, BindingResult bindingResult) {
        var res = Common.processFieldErrors(bindingResult, httpServletResponse);
        if(res != null) {
            return res;
        }

        ReturnObject ret = customerAccountService.modifyPassword(modifyPwdVo);
        return Common.decorateReturnObject(ret);
    }

    @PutMapping("/customers/password/reset")
    public Object resetPassword(@RequestBody ResetPwdVo resetPwdVo, BindingResult bindingResult) {
        var res = Common.processFieldErrors(bindingResult, httpServletResponse);
        if(res != null) {
            return res;
        }

        ReturnObject ret = customerAccountService.resetPassword(resetPwdVo);
        return Common.decorateReturnObject(ret);
    }

    @Audit(departName = "departs")
    @PutMapping("/shops/{did}/customers/{id}/ban")
    public Object banCustomer(@PathVariable Long did, @PathVariable Long id,
                              @LoginUser Long adminId, @LoginName String adminName) {
        if (!did.equals(0L)) {
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        ReturnObject returnObject = customerAccountService.banCustomer(id, adminId, adminName);
        return Common.decorateReturnObject(returnObject);
    }

    @Audit(departName = "departs")
    @PutMapping("/shops/{did}/customers/{id}/release")
    public Object releaseCustomer(@PathVariable Long did, @PathVariable Long id,
                              @LoginUser Long adminId, @LoginName String adminName) {
        if (!did.equals(0L)) {
            return new ReturnObject<>(ReturnNo.RESOURCE_ID_OUTSCOPE);
        }
        ReturnObject returnObject = customerAccountService.releaseCustomer(id, adminId, adminName);
        return Common.decorateReturnObject(returnObject);
    }
}
